home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / pbmplus / pbm / orig.libpbm1.c < prev    next >
Text File  |  1996-02-28  |  12KB  |  678 lines

  1. /* libpbm1.c - pbm utility library part 1
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pbm.h"
  14. #include "version.h"
  15. #include "libpbm.h"
  16. #if __STDC__
  17. #include <stdarg.h>
  18. #else /*__STDC__*/
  19. #include <varargs.h>
  20. #endif /*__STDC__*/
  21.  
  22.  
  23. /* Forward routines. */
  24.  
  25. #if defined(NEED_VFPRINTF1) || defined(NEED_VFPRINTF2)
  26. int vfprintf ARGS(( FILE* stream, char* format, va_list args ));
  27. #endif /*NEED_VFPRINTF*/
  28.  
  29.  
  30. /* Variable-sized arrays. */
  31.  
  32. char*
  33. pm_allocrow( cols, size )
  34.     int cols;
  35.     int size;
  36.     {
  37.     register char* itrow;
  38.  
  39.     itrow = (char*) malloc( cols * size );
  40.     if ( itrow == (char*) 0 )
  41.     pm_error( "out of memory allocating a row" );
  42.     return itrow;
  43.     }
  44.  
  45. void
  46. pm_freerow( itrow )
  47.     char* itrow;
  48.     {
  49.     free( itrow );
  50.     }
  51.  
  52.  
  53. char**
  54. pm_allocarray( cols, rows, size )
  55.     int cols, rows;
  56.     int size;
  57.     {
  58.     char** its;
  59.     int i;
  60.  
  61.     its = (char**) malloc( rows * sizeof(char*) );
  62.     if ( its == (char**) 0 )
  63.     pm_error( "out of memory allocating an array" );
  64.     its[0] = (char*) malloc( rows * cols * size );
  65.     if ( its[0] == (char*) 0 )
  66.     pm_error( "out of memory allocating an array" );
  67.     for ( i = 1; i < rows; ++i )
  68.     its[i] = &(its[0][i * cols * size]);
  69.     return its;
  70.     }
  71.  
  72. void
  73. pm_freearray( its, rows )
  74.     char** its;
  75.     int rows;
  76.     {
  77.     free( its[0] );
  78.     free( its );
  79.     }
  80.  
  81.  
  82. /* Case-insensitive keyword matcher. */
  83.  
  84. int
  85. pm_keymatch( str, keyword, minchars )
  86.     char* str;
  87.     char* keyword;
  88.     int minchars;
  89.     {
  90.     register int len;
  91.  
  92.     len = strlen( str );
  93.     if ( len < minchars )
  94.     return 0;
  95.     while ( --len >= 0 )
  96.     {
  97.     register char c1, c2;
  98.  
  99.     c1 = *str++;
  100.     c2 = *keyword++;
  101.     if ( c2 == '\0' )
  102.         return 0;
  103.     if ( isupper( c1 ) )
  104.         c1 = tolower( c1 );
  105.     if ( isupper( c2 ) )
  106.         c1 = tolower( c2 );
  107.     if ( c1 != c2 )
  108.         return 0;
  109.     }
  110.     return 1;
  111.     }
  112.  
  113.  
  114. /* Log base two hacks. */
  115.  
  116. int
  117. pm_maxvaltobits( maxval )
  118.     int maxval;
  119.     {
  120.     if ( maxval <= 1 )
  121.     return 1;
  122.     else if ( maxval <= 3 )
  123.     return 2;
  124.     else if ( maxval <= 7 )
  125.     return 3;
  126.     else if ( maxval <= 15 )
  127.     return 4;
  128.     else if ( maxval <= 31 )
  129.     return 5;
  130.     else if ( maxval <= 63 )
  131.     return 6;
  132.     else if ( maxval <= 127 )
  133.     return 7;
  134.     else if ( maxval <= 255 )
  135.     return 8;
  136.     else if ( maxval <= 511 )
  137.     return 9;
  138.     else if ( maxval <= 1023 )
  139.     return 10;
  140.     else if ( maxval <= 2047 )
  141.     return 11;
  142.     else if ( maxval <= 4095 )
  143.     return 12;
  144.     else if ( maxval <= 8191 )
  145.     return 13;
  146.     else if ( maxval <= 16383 )
  147.     return 14;
  148.     else if ( maxval <= 32767 )
  149.     return 15;
  150.     else if ( (long) maxval <= 65535L )
  151.     return 16;
  152.     else
  153.     pm_error( "maxval of %d is too large!", maxval );
  154.     }
  155.  
  156. int
  157. pm_bitstomaxval( bits )
  158.     int bits;
  159.     {
  160.     return ( 1 << bits ) - 1;
  161.     }
  162.  
  163.  
  164. /* Initialization. */
  165.  
  166. static char* progname;
  167. static int showmessages;
  168.  
  169. void
  170. pm_init( argcP, argv )
  171.     int* argcP;
  172.     char* argv[];
  173.     {
  174.     int argn, i;
  175.  
  176.     /* Extract program name. */
  177.     progname = rindex( argv[0], '/');
  178.     if ( progname == NULL )
  179.     progname = argv[0];
  180.     else
  181.     ++progname;
  182.  
  183.     /* Check for any global args. */
  184.     showmessages = 1;
  185.     for ( argn = 1; argn < *argcP; ++argn )
  186.     {
  187.     if ( pm_keymatch( argv[argn], "-quiet", 6 ) )
  188.         {
  189.         showmessages = 0;
  190.         }
  191.     else if ( pm_keymatch( argv[argn], "-version", 7 ) )
  192.         {
  193.         pm_message( "Version of %s", PBMPLUS_VERSION );
  194. #ifdef BSD
  195.         pm_message( "BSD defined" );
  196. #endif /*BSD*/
  197. #ifdef SYSV
  198.         pm_message( "SYSV defined" );
  199. #endif /*SYSV*/
  200. #ifdef MSDOS
  201.         pm_message( "MSDOS defined" );
  202. #endif /*MSDOS*/
  203. #ifdef PBMPLUS_RAWBITS
  204.         pm_message( "PBMPLUS_RAWBITS defined" );
  205. #endif /*PBMPLUS_RAWBITS*/
  206. #ifdef PBMPLUS_BROKENPUTC1
  207.         pm_message( "PBMPLUS_BROKENPUTC1 defined" );
  208. #endif /*PBMPLUS_BROKENPUTC1*/
  209. #ifdef PBMPLUS_BROKENPUTC2
  210.         pm_message( "PBMPLUS_BROKENPUTC2 defined" );
  211. #endif /*PBMPLUS_BROKENPUTC2*/
  212. #ifdef PGM_BIGGRAYS
  213.         pm_message( "PGM_BIGGRAYS defined" );
  214. #endif /*PGM_BIGGRAYS*/
  215. #ifdef PPM_PACKCOLORS
  216.         pm_message( "PPM_PACKCOLORS defined" );
  217. #endif /*PPM_PACKCOLORS*/
  218. #ifdef DEBUG
  219.         pm_message( "DEBUG defined" );
  220. #endif /*DEBUG*/
  221. #ifdef NEED_VFPRINTF1
  222.         pm_message( "NEED_VFPRINTF1 defined" );
  223. #endif /*NEED_VFPRINTF1*/
  224. #ifdef NEED_VFPRINTF2
  225.         pm_message( "NEED_VFPRINTF2 defined" );
  226. #endif /*NEED_VFPRINTF2*/
  227. #ifdef RGB_DB
  228.         pm_message( "RGB_DB=\"%s\"", RGB_DB );
  229. #endif /*RGB_DB*/
  230. #ifdef LIBTIFF
  231.         pm_message( "LIBTIFF defined" );
  232. #endif /*LIBTIFF*/
  233.         exit( 0 );
  234.         }
  235.     else
  236.         continue;
  237.     for ( i = argn + 1; i <= *argcP; ++i )
  238.         argv[i - 1] = argv[i];
  239.     --(*argcP);
  240.     }
  241.     }
  242.  
  243. void
  244. pbm_init( argcP, argv )
  245.     int* argcP;
  246.     char* argv[];
  247.     {
  248.     pm_init( argcP, argv );
  249.     }
  250.  
  251.  
  252. /* Error handling. */
  253.  
  254. void
  255. pm_usage( usage )
  256.     char* usage;
  257.     {
  258.     fprintf( stderr, "usage:  %s %s\n", progname, usage );
  259.     exit( 1 );
  260.     }
  261.  
  262. void
  263. pm_perror( reason )
  264.     char* reason;
  265.     {
  266.     extern char* sys_errlist[];
  267.     extern int errno;
  268.     char* e;
  269.  
  270.     e = sys_errlist[errno];
  271.  
  272.     if ( reason != 0 && reason[0] != '\0' )
  273.     pm_error( "%s - %s", reason, e );
  274.     else
  275.     pm_error( "%s", e );
  276.     }
  277.  
  278. #if __STDC__
  279. void
  280. pm_message( char* format, ... )
  281.     {
  282.     va_list args;
  283.  
  284.     va_start( args, format );
  285. #else /*__STDC__*/
  286. /*VARARGS1*/
  287. void
  288. pm_message( va_alist )
  289.     va_dcl
  290.     { /*}*/
  291.     va_list args;
  292.     char* format;
  293.  
  294.     va_start( args );
  295.     format = va_arg( args, char* );
  296. #endif /*__STDC__*/
  297.  
  298.     if ( showmessages )
  299.     {
  300.     fprintf( stderr, "%s: ", progname );
  301.     (void) vfprintf( stderr, format, args );
  302.     fputc( '\n', stderr );
  303.     }
  304.     va_end( args );
  305.     }
  306.  
  307. #if __STDC__
  308. void
  309. pm_error( char* format, ... )
  310.     {
  311.     va_list args;
  312.  
  313.     va_start( args, format );
  314. #else /*__STDC__*/
  315. /*VARARGS1*/
  316. void
  317. pm_error( va_alist )
  318.     va_dcl
  319.     { /*}*/
  320.     va_list args;
  321.     char* format;
  322.  
  323.     va_start( args );
  324.     format = va_arg( args, char* );
  325. #endif /*__STDC__*/
  326.  
  327.     fprintf( stderr, "%s: ", progname );
  328.     (void) vfprintf( stderr, format, args );
  329.     fputc( '\n', stderr );
  330.     va_end( args );
  331.     exit( 1 );
  332.     }
  333.  
  334. #ifdef NEED_VFPRINTF1
  335.  
  336. /* Micro-vfprintf, for systems that don't have vfprintf but do have _doprnt.
  337. */
  338.  
  339. int
  340. vfprintf( stream, format, args )
  341.     FILE* stream;
  342.     char* format;
  343.     va_list args;
  344.     {
  345.     return _doprnt( format, args, stream );
  346.     }
  347. #endif /*NEED_VFPRINTF1*/
  348.  
  349. #ifdef NEED_VFPRINTF2
  350.  
  351. /* Portable mini-vfprintf, for systems that don't have either vfprintf or
  352. ** _doprnt.  This depends only on fprintf.  If you don't have fprintf,
  353. ** you might consider getting a new stdio library.
  354. */
  355.  
  356. int
  357. vfprintf( stream, format, args )
  358.     FILE* stream;
  359.     char* format;
  360.     va_list args;
  361.     {
  362.     int n;
  363.     char* ep;
  364.     char fchar;
  365.     char tformat[512];
  366.     int do_long;
  367.     int i;
  368.     long l;
  369.     unsigned u;
  370.     unsigned long ul;
  371.     char* s;
  372.     double d;
  373.  
  374.     n = 0;
  375.     while ( *format != '\0' )
  376.     {
  377.     if ( *format != '%' )
  378.         { /* Not special, just write out the char. */
  379.         (void) putc( *format, stream );
  380.         ++n;
  381.         ++format;
  382.         }
  383.     else
  384.         {
  385.         do_long = 0;
  386.         ep = format + 1;
  387.  
  388.         /* Skip over all the field width and precision junk. */
  389.         if ( *ep == '-' )
  390.         ++ep;
  391.         if ( *ep == '0' )
  392.         ++ep;
  393.         while ( isdigit( *ep ) )
  394.         ++ep;
  395.         if ( *ep == '.' )
  396.         {
  397.         ++ep;
  398.         while ( isdigit( *ep ) )
  399.             ++ep;
  400.         }
  401.         if ( *ep == '#' )
  402.         ++ep;
  403.         if ( *ep == 'l' )
  404.         {
  405.         do_long = 1;
  406.         ++ep;
  407.         }
  408.  
  409.         /* Here's the field type.  Extract it, and copy this format
  410.         ** specifier to a temp string so we can add an end-of-string.
  411.         */
  412.         fchar = *ep;
  413.         (void) strncpy( tformat, format, ep - format + 1 );
  414.         tformat[ep - format + 1] = '\0';
  415.  
  416.         /* Now do a one-argument fprintf with the format string we have
  417.         ** isolated.
  418.         */
  419.         switch ( fchar )
  420.         {
  421.         case 'd':
  422.         if ( do_long )
  423.             {
  424.             l = va_arg( args, long );
  425.             n += fprintf( stream, tformat, l );
  426.             }
  427.         else
  428.             {
  429.             i = va_arg( args, int );
  430.             n += fprintf( stream, tformat, i );
  431.             }
  432.         break;
  433.  
  434.             case 'o':
  435.             case 'x':
  436.             case 'X':
  437.             case 'u':
  438.         if ( do_long )
  439.             {
  440.             ul = va_arg( args, unsigned long );
  441.             n += fprintf( stream, tformat, ul );
  442.             }
  443.         else
  444.             {
  445.             u = va_arg( args, unsigned );
  446.             n += fprintf( stream, tformat, u );
  447.             }
  448.         break;
  449.  
  450.             case 'c':
  451.         i = (char) va_arg( args, int );
  452.         n += fprintf( stream, tformat, i );
  453.         break;
  454.  
  455.             case 's':
  456.         s = va_arg( args, char* );
  457.         n += fprintf( stream, tformat, s );
  458.         break;
  459.  
  460.             case 'e':
  461.             case 'E':
  462.             case 'f':
  463.             case 'g':
  464.             case 'G':
  465.         d = va_arg( args, double );
  466.         n += fprintf( stream, tformat, d );
  467.         break;
  468.  
  469.             case '%':
  470.         (void) putc( '%', stream );
  471.         ++n;
  472.         break;
  473.  
  474.         default:
  475.         return -1;
  476.         }
  477.  
  478.         /* Resume formatting on the next character. */
  479.         format = ep + 1;
  480.         }
  481.     }
  482.     return nc;
  483.     }
  484. #endif /*NEED_VFPRINTF2*/
  485.  
  486.  
  487. /* File open/close that handles "-" as stdin and checks errors. */
  488.  
  489. FILE*
  490. pm_openr( name )
  491.     char* name;
  492.     {
  493.     FILE* f;
  494.  
  495.     if ( strcmp( name, "-" ) == 0 )
  496.     f = stdin;
  497.     else
  498.     {
  499. #ifdef MSDOS
  500.     f = fopen( name, "rb" );
  501. #else /*MSDOS*/
  502.     f = fopen( name, "r" );
  503. #endif /*MSDOS*/
  504.     if ( f == NULL )
  505.         {
  506.         pm_perror( name );
  507.         exit( 1 );
  508.         }
  509.     }
  510.     return f;
  511.     }
  512.  
  513. FILE*
  514. pm_openw( name )
  515.     char* name;
  516.     {
  517.     FILE* f;
  518.  
  519. #ifdef MSDOS
  520.     f = fopen( name, "wb" );
  521. #else /*MSDOS*/
  522.     f = fopen( name, "w" );
  523. #endif /*MSDOS*/
  524.     if ( f == NULL )
  525.     {
  526.     pm_perror( name );
  527.     exit( 1 );
  528.     }
  529.     return f;
  530.     }
  531.  
  532. void
  533. pm_close( f )
  534.     FILE* f;
  535.     {
  536. #ifdef POSIX
  537.     fflush( f );
  538. #endif
  539.     if ( ferror( f ) )
  540.     pm_message( "a file read or write error occurred at some point" );
  541.     if ( f != stdin )
  542.     if ( fclose( f ) != 0 )
  543.         pm_perror( "fclose" );
  544.     }
  545.  
  546. /* Endian I/O.
  547. */
  548.  
  549. int
  550. pm_readbigshort( in, sP )
  551.     FILE* in;
  552.     short* sP;
  553.     {
  554.     int c;
  555.  
  556.     if ( (c = getc( in )) == EOF )
  557.     return -1;
  558.     *sP = ( c & 0xff ) << 8;
  559.     if ( (c = getc( in )) == EOF )
  560.     return -1;
  561.     *sP |= c & 0xff;
  562.     return 0;
  563.     }
  564.  
  565. #if __STDC__
  566. int
  567. pm_writebigshort( FILE* out, short s )
  568. #else /*__STDC__*/
  569. int
  570. pm_writebigshort( out, s )
  571.     FILE* out;
  572.     short s;
  573. #endif /*__STDC__*/
  574.     {
  575.     (void) putc( ( s >> 8 ) & 0xff, out );
  576.     (void) putc( s & 0xff, out );
  577.     return 0;
  578.     }
  579.  
  580. int
  581. pm_readbiglong( in, lP )
  582.     FILE* in;
  583.     long* lP;
  584.     {
  585.     int c;
  586.  
  587.     if ( (c = getc( in )) == EOF )
  588.     return -1;
  589.     *lP = ( c & 0xff ) << 24;
  590.     if ( (c = getc( in )) == EOF )
  591.     return -1;
  592.     *lP |= ( c & 0xff ) << 16;
  593.     if ( (c = getc( in )) == EOF )
  594.     return -1;
  595.     *lP |= ( c & 0xff ) << 8;
  596.     if ( (c = getc( in )) == EOF )
  597.     return -1;
  598.     *lP |= c & 0xff;
  599.     return 0;
  600.     }
  601.  
  602. int
  603. pm_writebiglong( out, l )
  604.     FILE* out;
  605.     long l;
  606.     {
  607.     (void) putc( ( l >> 24 ) & 0xff, out );
  608.     (void) putc( ( l >> 16 ) & 0xff, out );
  609.     (void) putc( ( l >> 8 ) & 0xff, out );
  610.     (void) putc( l & 0xff, out );
  611.     return 0;
  612.     }
  613.  
  614. int
  615. pm_readlittleshort( in, sP )
  616.     FILE* in;
  617.     short* sP;
  618.     {
  619.     int c;
  620.  
  621.     if ( (c = getc( in )) == EOF )
  622.     return -1;
  623.     *sP = c & 0xff;
  624.     if ( (c = getc( in )) == EOF )
  625.     return -1;
  626.     *sP |= ( c & 0xff ) << 8;
  627.     return 0;
  628.     }
  629.  
  630. #if __STDC__
  631. int
  632. pm_writelittleshort( FILE* out, short s )
  633. #else /*__STDC__*/
  634. int
  635. pm_writelittleshort( out, s )
  636.     FILE* out;
  637.     short s;
  638. #endif /*__STDC__*/
  639.     {
  640.     (void) putc( s & 0xff, out );
  641.     (void) putc( ( s >> 8 ) & 0xff, out );
  642.     return 0;
  643.     }
  644.  
  645. int
  646. pm_readlittlelong( in, lP )
  647.     FILE* in;
  648.     long* lP;
  649.     {
  650.     int c;
  651.  
  652.     if ( (c = getc( in )) == EOF )
  653.     return -1;
  654.     *lP = c & 0xff;
  655.     if ( (c = getc( in )) == EOF )
  656.     return -1;
  657.     *lP |= ( c & 0xff ) << 8;
  658.     if ( (c = getc( in )) == EOF )
  659.     return -1;
  660.     *lP |= ( c & 0xff ) << 16;
  661.     if ( (c = getc( in )) == EOF )
  662.     return -1;
  663.     *lP |= ( c & 0xff ) << 24;
  664.     return 0;
  665.     }
  666.  
  667. int
  668. pm_writelittlelong( out, l )
  669.     FILE* out;
  670.     long l;
  671.     {
  672.     (void) putc( l & 0xff, out );
  673.     (void) putc( ( l >> 8 ) & 0xff, out );
  674.     (void) putc( ( l >> 16 ) & 0xff, out );
  675.     (void) putc( ( l >> 24 ) & 0xff, out );
  676.     return 0;
  677.     }
  678.